home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Database / Evaluator / SQLWindow.m < prev   
Text File  |  1993-11-01  |  4KB  |  157 lines

  1. /* SQLWindow.m:
  2.  * You may freely copy, distribute, and reuse the code in this example.
  3.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  4.  * fitness for any particular use.
  5.  *
  6.  * Written by Jack Greenfield
  7.  *
  8.  */
  9.  
  10. #import    "ScrollViewExtras.h"
  11. #import "SQLWindow.h"
  12. #import    "MultiBinder.h"
  13.  
  14. #define FAILURE NXLocalizedString("Failure:", NULL, \
  15.     "Message given to user when an operation has failed.")
  16.  
  17. #define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
  18.     "Message given to user to explain what fails. ")
  19.  
  20. #define OK NXLocalizedString("OK", NULL, "Okay to continue ")
  21.  
  22. @implementation SQLWindow
  23.  
  24. - free
  25. {
  26.     [database free];
  27.     return [super free];
  28. }
  29.  
  30. - initWithFile:(const char *)filename
  31. {
  32.     char path[MAXPATHLEN];
  33.  
  34.     if ((self = [super init]) != nil)
  35.     {
  36.     database = [[DBDatabase alloc] initFromFile:filename];
  37.     if (![database connect])
  38.     {
  39.         NXRunAlertPanel(FAILURE, CANNOT_CONNECT, OK, NULL, NULL);
  40.         return [self free];
  41.     }
  42.  
  43.     [[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
  44.     [NXApp loadNibFile:path owner:self withNames:NO];
  45.     [[resultsView window] setDelegate:self];
  46.     [[resultsView window] setTitleAsFilename:filename];
  47.     [[queryView docView] selectAll:self];
  48.     [[resultsView window] makeKeyAndOrderFront:self];
  49.     }
  50.  
  51.     return self;
  52. }
  53.  
  54. - database { return database; }
  55.  
  56. - evaluate:sender
  57. {
  58.     int    charCount;
  59.     char *buffer;
  60.     MultiBinder *binder;
  61.     List * rowsList;
  62.     
  63.     if ((charCount = [[queryView docView] textLength]) > 0)
  64.     {
  65.     binder = [[MultiBinder alloc] initFromPropertyLists:nil];
  66.     [binder setDatabase:database];
  67.     [binder setDelegate:self];
  68.     rowsList = [[List alloc] init];
  69.         /* This casting is needed to avoid the compiler warning
  70.            that List doesn't implement DBContainers protocol
  71.          */
  72.     [binder setContainer: (id)rowsList];
  73.  
  74.     buffer = (char *) alloca(1 + charCount);
  75.     [[queryView docView] getSubstring:buffer start:0 length:charCount];
  76.     buffer[charCount] = 0;
  77.     while (charCount > 0 && buffer[--charCount] == '\n')
  78.         buffer[charCount] = 0;
  79.  
  80.     [resultsView sprintf:"%s\n", buffer];
  81.     if (![binder evaluateString:buffer])
  82.         [resultsView sprintf:"EVALUATION FAILED\n\n"];
  83.      
  84.     if (![binder fetch])
  85.         [resultsView sprintf:"FETCH FAILED\n\n"];
  86.     else
  87.             /* For the last result set, binderWillChangeResultSet
  88.              * needs to be called explicitly.
  89.              */
  90.         [self binderWillChangeResultSet:binder];
  91.     
  92.     [resultsView sprintf:"\n"];
  93.     [binder free];
  94.     [rowsList free];
  95.     }
  96.  
  97.     [[queryView docView] selectText:self];
  98.     return self;
  99. }
  100.  
  101. - clear:sender
  102. {
  103.     [resultsView clear:sender];
  104.     [[queryView docView] selectText:self];
  105.     return self;
  106. }
  107.  
  108. - print:sender
  109. {
  110.     [resultsView print:sender];
  111.     [[queryView docView] selectText:self];
  112.     return self;
  113. }
  114.  
  115. /* This delegate method will be called every time a new result set is being
  116.  * fetched. All objects returned by the binder fetch can be retrieved from the 
  117.  * binder container (named rowsList here). Note that the container will get
  118.  * flushed everytime a new result set is retrieved. This delegate method is the
  119.  * place where you can save the result set elsewhere if needed.
  120.  */
  121. - binderWillChangeResultSet:(MultiBinder *)binder
  122. {
  123.     int rowsIndex;
  124.     int rowsCount;
  125.     int propIndex;
  126.     int propCount;
  127.     List *rowsList;
  128.     List *propList;
  129.     
  130.     propList = [[List alloc] init];
  131.     [binder getCurrentProperties:propList];
  132.     
  133.     rowsList = [binder container];
  134.     rowsCount = [rowsList count];
  135.     [resultsView sprintf:"\nresult set %d\n", [binder currentResultSet]];
  136.     [resultsView sprintf:"%u records selected\n", rowsCount];
  137.     [binder setFirst];
  138.     for (rowsIndex = 0; rowsIndex < rowsCount; ++rowsIndex)
  139.     {
  140.     propCount = [propList count];
  141.     for (propIndex = 0; propIndex < propCount; ++propIndex)
  142.     {
  143.         id p = [propList objectAt:propIndex];
  144.         [resultsView sprintf:"%s=(%s) ", 
  145.         [p name], [[binder valueForProperty:p] stringValue]];
  146.     }
  147.  
  148.     [resultsView sprintf:"\n"];
  149.     [binder setNext];
  150.     }
  151.  
  152.     [propList free];
  153.     return self;
  154. }
  155.  
  156. @end
  157.